package com.csust.educodesandbox.utils;

import cn.hutool.core.util.StrUtil;
import com.csust.educodesandbox.model.ExecuteMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.io.*;

/**
 * @ClassNameProcessUtil
 * @Description 进程工具类
 * @Author钰玟
 * @Date2025/6/25 下午4:17
 * @Version 1.0
 **/
@Component
@Slf4j
public class ProcessUtil {
    /**
     * 通过进程编译/执行代码
     * @param compileProcess 编译进程
     * @param opName 操作名称
     * @return 运行结果
     */
    public static ExecuteMessage processExecuteAndGetMessage(Process compileProcess, String opName) {
        ExecuteMessage executeMessage = new ExecuteMessage();
        // 计时 (时间复杂度)
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        try {
            //2.3得到状态执行码
            int exitValue = compileProcess.waitFor();
            // 设置状态码
            executeMessage.setExitValue(exitValue);
            //2.4通过状态执行判断
            if (exitValue == 0) {
                //编译成功
                log.info("{}成功", opName);
                //通过流来得到正常输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(compileProcess.getInputStream()));
                StringBuilder stringBuilder = new StringBuilder();
                String compileOutputLine;

                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    stringBuilder.append(compileOutputLine);
                }
                executeMessage.setMessage(stringBuilder.toString());
                log.info("{}输出：{}", opName, stringBuilder.toString());
            } else {
                //异常退出
                log.error("{}失败,错误码:{}", opName, exitValue);
                //通过流来得到正常输出
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(compileProcess.getInputStream()));
                StringBuilder stringBuilder = new StringBuilder();
                String compileOutputLine;

                while ((compileOutputLine = bufferedReader.readLine()) != null) {
                    stringBuilder.append(compileOutputLine);
                }

                //通过流来得到正常输出
                BufferedReader errorBufferedReader = new BufferedReader(new InputStreamReader(compileProcess.getInputStream()));
                StringBuilder errorStringBuilder = new StringBuilder();
                String errorCompileOutputLine;
                while ((errorCompileOutputLine = errorBufferedReader.readLine()) != null) {
                    errorStringBuilder.append(errorCompileOutputLine);
                }
                executeMessage.setErrorMessage(errorStringBuilder.toString());
                log.info(opName + "输出：{}", stringBuilder.toString());
            }
        } catch (Exception e) {
            log.error("fail to {},the reason is {}", opName,e.getMessage());
            throw new RuntimeException(e);
        }finally {
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getTotalTimeMillis());
        }
        return executeMessage;
    }
    /**
     * 执行交互式进程并获取信息
     *
     * @param runProcess
     * @param args
     * @return
     */
    public static ExecuteMessage runInteractProcessAndGetMessage(Process runProcess, String args) {
        ExecuteMessage executeMessage = new ExecuteMessage();

        try {
            // 向控制台输入程序
            OutputStream outputStream = runProcess.getOutputStream();
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
            String[] s = args.split(" ");
            String join = StrUtil.join("\n", s) + "\n";
            outputStreamWriter.write(join);
            // 相当于按了回车，执行输入的发送
            outputStreamWriter.flush();

            // 分批获取进程的正常输出
            InputStream inputStream = runProcess.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder compileOutputStringBuilder = new StringBuilder();
            // 逐行读取
            String compileOutputLine;
            while ((compileOutputLine = bufferedReader.readLine()) != null) {
                compileOutputStringBuilder.append(compileOutputLine);
            }
            executeMessage.setMessage(compileOutputStringBuilder.toString());
            // 记得资源的释放，否则会卡死
            outputStreamWriter.close();
            outputStream.close();
            inputStream.close();
            runProcess.destroy();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return executeMessage;
    }


}
